package C8_15_ReplaceTypeCodeWithStateStrategy;

import org.junit.Test;

/**
 * @author xufy
 * @version 1.0
 * @description 以 State/Strategy 取代类型码
 **/
public class ReplaceTypeCodeWithStateStrategy {

    /**
     * 重构前
     */
    @Test
    public void test1() {
        Employee employee = new Employee(Employee.ENGINEER);
        System.out.println("重构前：" + employee.getType() + " , " + employee.payAmount());
    }

    /**
     * 重构后
     */
    @Test
    public void test2() {
        Employee2 employee2 = new Employee2(EmployeeType.ENGINEER);
        System.out.println("重构后：" + employee2.getType() + " , " + employee2.payAmount());
    }

}

class Employee {

    private int _type;
    static final int ENGINEER = 0;
    static final int SALESMAN = 1;
    static final int MANAGER = 2;

    Employee(int type) {
        _type = type;
    }

    int getType() {
        return _type;
    }

    int payAmount() {
        switch (_type) {
            case ENGINEER:
                return 10;
            case SALESMAN:
                return 100;
            case MANAGER:
                return 1000;
            default:
                throw new RuntimeException("Incorrect Employee");
        }

    }
}
/**
 * 重构后
 */
class Employee2 {

    private EmployeeType _type;


    Employee2(int arg) {
        setType(arg);
    }

    void setType(int arg) {
        _type = EmployeeType.newType(arg);
    }

    int getType() {
        return _type.getTypeCode();
    }

    int payAmount() {
        switch (getType()) {
            case EmployeeType.ENGINEER:
                return 10;
            case EmployeeType.SALESMAN:
                return 100;
            case EmployeeType.MANAGER:
                return 1000;
            default:
                throw new RuntimeException("Incorrect Employee");
        }

    }
}

abstract class EmployeeType {
    static final int ENGINEER = 0;
    static final int SALESMAN = 1;
    static final int MANAGER = 2;

    abstract int getTypeCode();

    static EmployeeType newType(int code) {
        switch (code) {
            case ENGINEER:
                return new Engineer();
            case SALESMAN:
                return new Salesman();
            case MANAGER:
                return new Manager();
            default:
                throw new IllegalArgumentException("Incorrect type code value");
        }
    }

}

class Engineer extends EmployeeType {

    @Override
    int getTypeCode() {
        return EmployeeType.ENGINEER;
    }
}

class Manager extends EmployeeType {

    @Override
    int getTypeCode() {
        return EmployeeType.MANAGER;
    }
}

class Salesman extends EmployeeType {

    @Override
    int getTypeCode() {
        return EmployeeType.SALESMAN;
    }
}
